home *** CD-ROM | disk | FTP | other *** search
/ PC Graphics Unleashed / PC Graphics Unleashed.iso / ch01 / viper.asm < prev    next >
Assembly Source File  |  1993-12-06  |  14KB  |  495 lines

  1. ;--------------------------------------------------------------------------
  2. ; This is file VIPER.ASM
  3. ;
  4. ; Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  5. ; Copyright (C) 1992 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221
  6. ;
  7. ; This file is distributed under the terms listed in the document
  8. ; "copying.dj", available from DJ Delorie at the address above.
  9. ; A copy of "copying.dj" should accompany this file; if not, a copy
  10. ; should be available from where this file was obtained.  This file
  11. ; may not be distributed without a verbatim copy of "copying.dj".
  12. ;
  13. ; This file is distributed WITHOUT ANY WARRANTY; without even the implied
  14. ; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. ;--------------------------------------------------------------------------
  16.  
  17. _TEXT    segment byte public 'CODE'
  18. _TEXT    ends
  19. DGROUP  group    _TEXT,_DATA,_BSS
  20.     assume  cs:_TEXT,ds:DGROUP
  21. _DATA    segment word public 'DATA'
  22. d@    label    byte
  23. d@w    label    word
  24. _DATA    ends
  25. _BSS    segment word public 'BSS'
  26. b@    label    byte
  27. b@w    label    word
  28. _BSS    ends
  29. _TEXT    segment byte public 'CODE'
  30.     assume  cs:_TEXT,ds:DGROUP
  31.  
  32. include grdriver.inc
  33.  
  34. ;--------------------------------------------------------------------------
  35. ; DRIVER HEADER
  36. ;  The following entries MUST match the structure and constant
  37. ;  declarations in the file 'grdriver.h' of the GRX graphics library
  38. ;  The mode word should contain the following bitfields:
  39. ;     - the GRD_NEW_DRIVER bit set for any new format driver
  40. ;     - the adapter type field should be specified
  41. ;     - the memory size field should be specified
  42. ;     - the paging mode field should be specified
  43. ;  The mode set routine will OR in the plane bitfield as it will
  44. ;  change when different color number modes are requested.
  45. ;--------------------------------------------------------------------------
  46.  
  47.     dw    offset mode_set_routine
  48.     dw    offset paging_routine
  49. mode_W  dw    GRD_NEW_DRIVER+GRD_VGA+GRD_1024K+GRD_NO_RW
  50. ;
  51. ; The 'def_xx' fields are filled in by go32 from the corresponding
  52. ; fields of the 'GO32' environment variable
  53. ;
  54. def_tw  dw    80        ; text width
  55. def_th  dw    25        ; text height
  56. def_gw  dw    640        ; graphics width
  57. def_gh  dw    480        ; graphics height
  58. def_nc  dw    256        ; graphics colors
  59.     dw    offset driver_init_routine
  60.     dw    offset text_mode_table
  61.     dw    offset graphics_mode_table
  62.  
  63. ;
  64. ; Biggest text and graphics sizes
  65. ;
  66. Max_TW  equ    80
  67. Max_TH  equ    50
  68. Max_GWn equ    800        ; non interlaced!!!
  69. Max_GHn equ    600
  70. Max_GW  equ    1152        ; may be interlaced
  71. Max_GH  equ    900
  72.  
  73.  
  74. ;--------------------------------------------------------------------------
  75. ; TABLE OF SUPPORTED TEXT MODES
  76. ;    - keep sorted by size
  77. ;    - end with an all 0 entry
  78. ;    - BIOS field = 0xff disables it
  79. ;    - fields:
  80. ;        width,  height, colors, BIOS#+  setup_procedure_index*256
  81. ;--------------------------------------------------------------------------
  82. text_mode_table        label word
  83.     dw    80,    25,    2,    007h +  00000h
  84.     dw    40,    25,    16,    001h +  00000h
  85.     dw    80,    25,    16,    003h +  00000h
  86.     dw    80,    28,    16,    003h +  00400h  ; 80x25 + reload 14 row font
  87.     dw    80,    50,    16,    003h +  00600h  ; 80x25 + reload 8 row font
  88.     dw    132,    25,    16,    109h +  00000h  ; VESA 109h mode
  89.     dw    132,    28,    16,    109h +  00400h  ; VESA 109h mode (132x25) + reload 14 row font
  90.     dw    132,    44,    16,    10ah +  00000h  ; VESA 10ah mode
  91.     dw    132,    50,    16,    109h +  00600h  ; VESA 109h mode (132x25) + reload 8 row font
  92.     dw    0,    0,    0,    000h +  00000h
  93.  
  94. ;--------------------------------------------------------------------------
  95. ; TABLE OF SUPPORTED GRAPHICS MODES
  96. ;    - keep sorted first by colors then by size
  97. ;    - end with an all 0 entry
  98. ;    - BIOS field = 0xff disables it
  99. ;    - fields:
  100. ;        width,  height, colors, BIOS#+  setup_procedure_index*256
  101. ;--------------------------------------------------------------------------
  102. graphics_mode_table    label word
  103.     dw    320,    200,    16,    00dh +  00000h
  104.     dw    640,    200,    16,    00eh +  00000h
  105.     dw    640,    350,    16,    010h +  00000h
  106.     dw    640,    480,    16,    012h +  00000h
  107.     dw    800,    600,    16,    06ah +  00000h  ; VESA 06ah mode
  108.     dw    320,    200,    256,    013h +  00000h
  109.     dw    640,    480,    256,    101h +  00000h  ; VESA 101h mode
  110.     dw    800,    600,    256,    103h +  00000h  ; VESA 103h mode
  111.     dw     1024,    768,    256,    105h +  00000h  ; VESA 105h mode
  112.     dw     1152,    900,    256,    122h +  00000h  ; VESA 122h mode
  113.     dw    0,    0,    0,    000h +  00000h
  114.  
  115. ;--------------------------------------------------------------------------
  116. ; TABLE OF SPECIAL SETUP PROCEDURES
  117. ;  You may need such procedures for:
  118. ;     -- reloading fonts on standard EGA or VGA for
  119. ;     higher resolution text modes
  120. ;     -- enable HiColor mode of some Super VGAs
  121. ;     -- Handle the parameter passing conventions of the VESA BIOS
  122. ;     -- put VGA into 256 color plane mode ("MODE X")
  123. ;     -- etc...
  124. ;  There should be one entry in the table for every non-zero
  125. ;  'setup_procedure_index' in the text and graphics mode tables.
  126. ;  The first entry in the table belongs to index 100h, and so on.
  127. ;  The special setup procedure is invoked via a near call.
  128. ;
  129. ;  Entry: DI=address of the mode record from the text or graphics
  130. ;      table to set up.
  131. ;
  132. ;  Exit:  Adapter configured
  133. ;      BX=driver mode word as it should be returned by the mode set
  134. ;         routine. Typically it involves picking up the mode word
  135. ;         from the header and OR-ing in the appropriate bitplane mode
  136. ;         bitfield. (This is not needed for text modes)
  137. ;      AX, CX, DX, SI can be trashed, PRESERVE DI!!!!
  138. ;
  139. ;  NOTE: This runs in real mode, but don't mess with the segment registers.
  140. ;--------------------------------------------------------------------------
  141. special_setup_table    label word
  142.     dw    offset  VESA_SVGA_mode_set    ; for 01xxh modes
  143.     dw    offset  VESA_S3_mode_set    ; for 02xxh accelerated S3 modes
  144.     dw    0
  145.     dw    offset  VGA_28_row_mode_set    ; for 28 row text modes
  146.     dw    offset  VGA_28_row_mode_set    ; for 28 row VESA text modes
  147.     dw    offset  VGA_50_row_mode_set    ; for 50 row text modes
  148.     dw    offset  VGA_50_row_mode_set    ; for 50 row VESA text modes
  149.  
  150. ;
  151. ; Routine to set up VGA 50 row mode
  152. ; interface is described above
  153. ;
  154. VGA_50_row_mode_set    proc    near
  155.     mov    ax,WORD PTR [di+6]    ; get base mode number
  156.     and    ah,1            ; clear setup proc index
  157.     je    std_50_mode
  158.     mov    bx,ax
  159.     mov    ax,4f02h
  160.     int    10h
  161.     cmp    ax,004fh        ; VESA error ?
  162.     je    mode_50_done
  163.     mov    ax,3            ; VESA error -- set 80x25 mode
  164. std_50_mode:
  165.     int    10h
  166. mode_50_done:
  167.     xor    bx,bx
  168.     mov    ax,1112h        ; load 8x8 font
  169.     int    10h
  170.     ret
  171. VGA_50_row_mode_set    endp
  172.  
  173. ;
  174. ; Routine to set up VGA 28 row mode
  175. ; interface is described above
  176. ;
  177. VGA_28_row_mode_set     proc     near
  178.     mov    ax,WORD PTR [di+6]    ; get base mode number
  179.     and    ah,1            ; clear setup proc index
  180.     je    std_28_mode
  181.     mov    bx,ax
  182.     mov    ax,4f02h
  183.     int    10h
  184.     cmp    ax,004fh        ; VESA error ?
  185.     je    mode_28_done
  186.     mov    ax,3            ; VESA error -- set 80x25 mode
  187. std_28_mode:
  188.     int    10h
  189. mode_28_done:
  190.     xor    bx,bx
  191.     mov    ax,1111h        ; load 8x14 font
  192.     int    10h
  193.     ret
  194. VGA_28_row_mode_set     endp
  195.  
  196. ;
  197. ; Routine to set up VESA SVGA modes
  198. ; only used for 16 color text and graphics modes
  199. ; interface is described above
  200. ;
  201. VESA_SVGA_mode_set    proc    near
  202.     mov    ax,13h                ; the VIPER is a piece of s...! This hack seems
  203.     int    10h                ; to fix it most of the time. Don't ask me why!
  204.     mov    ax,4f02h
  205.     mov    bx,WORD PTR [di+6]
  206.     int    10h
  207.     mov    bx,0ffffh            ; error code
  208.     cmp    ax,004fh
  209.     jne    VESA_SVGA_done
  210.     mov    bx,GRD_4_PLANES
  211.     or    bx,mode_W
  212.     cmp    WORD PTR [di+4],16        ; 16 colors ?
  213.     je    VESA_SVGA_done
  214.     mov    bx,GRD_8_PLANES
  215.     or    bx,mode_W
  216. ;;      xor      bx,(GRD_VGA XOR GRD_S3)
  217.     cmp    WORD PTR [di+4],256        ; 256 colors ?
  218.     je    VESA_SVGA_done
  219.     mov    bx,GRD_16_PLANES
  220.     or    bx,mode_W
  221. VESA_SVGA_done:
  222.     ret
  223. VESA_SVGA_mode_set    endp
  224.  
  225. ; Routine to set up VESA S3 modes
  226. ; only used for 256 color graphics modes
  227. ; interface is described above
  228. ;
  229. VESA_S3_mode_set    proc    near
  230.     mov    ax,4f02h
  231.     mov    bx,WORD PTR [di+6]
  232.     int    10h
  233.     mov    bx,0ffffh        ; error code
  234.     cmp    ax,004fh
  235.     jne    VESA_S3_error
  236.     mov    bx,mode_W
  237.     xor    bx,(GRD_VGA XOR GRD_S3)
  238.     or    bx,GRD_8_PLANES
  239. VESA_S3_error:
  240.     ret
  241. VESA_S3_mode_set    endp
  242.  
  243.  
  244. ;--------------------------------------------------------------------------
  245. ; DRIVER INIT ROUTINE
  246. ;  called once after the driver is loaded
  247. ;  may do one or more of the followings:
  248. ;    - check for proper board type
  249. ;    - check amount of RAM on board, and:
  250. ;    -- update word in header to reflect correct amount
  251. ;    -- disable modes in the tables for which there is not enough RAM
  252. ;    - check for special equipment (HiColor DAC, etc...)
  253. ;
  254. ;  Entry: nothing
  255. ;
  256. ;  Exit:  AX=status:
  257. ;       non-zero: OK,
  258. ;       0: something went wrong (e.g. wrong adapter, etc..)
  259. ;      BX,CX,DX may be trashed
  260. ;
  261. ;  NOTE: This runs in real mode, but don't mess with the segment registers.
  262. ;--------------------------------------------------------------------------
  263. driver_init_routine    proc    far
  264.     push    di
  265.     push    es
  266.     sub    sp,256
  267.     mov    di,sp
  268.     mov    ax,ss
  269.     mov    es,ax
  270.     mov    ax,4f00h
  271.     int    10h        ; check for VESA BIOS
  272.     cmp    ax,004fh
  273.     jne    init_error
  274.     cmp    BYTE PTR es:[di+0],'V'
  275.     jne    init_error
  276.     cmp    BYTE PTR es:[di+1],'E'
  277.     jne    init_error
  278.     cmp    BYTE PTR es:[di+2],'S'
  279.     jne    init_error
  280.     cmp    BYTE PTR es:[di+3],'A'
  281.     jne    init_error
  282.     mov    ax,1        ; OK, VESA BIOS found
  283.     jmp    init_done
  284. init_error:
  285.     xor    ax,ax
  286. init_done:
  287.     add    sp,256
  288.     pop    es
  289.     pop    di
  290.     ret
  291. driver_init_routine    endp
  292.  
  293.  
  294. ;--------------------------------------------------------------------------
  295. ; MODE SET ROUTINE
  296. ;  sets up a text or graphics mode as close as possible to the one
  297. ;  reguested by the user with regard to number of colors and size.
  298. ;
  299. ;  Entry: AX=mode selection
  300. ;     0 = 80x25 text
  301. ;     1 = default text
  302. ;     2 = text CX cols by DX rows
  303. ;     3 = biggest text
  304. ;     4 = 320x200 graphics
  305. ;     5 = default graphics
  306. ;     6 = graphics CX width by DX height
  307. ;     7 = biggest non-interlaced graphics
  308. ;     8 = biggest graphics
  309. ;     9 = graphics BX colors, CX width by DX height
  310. ;
  311. ;  Exit: BX=driver mode flag
  312. ;     CX=width (in pixels or characters)
  313. ;     DX=height
  314. ;
  315. ;  NOTE: This runs in real mode, but don't mess with the segment registers.
  316. ;     YOU SHOULD NOT NEED TO CHANGE THIS ROUTINE AS IT IS PRETTY
  317. ;     MUCH TABLE DRIVEN
  318. ;--------------------------------------------------------------------------
  319. mode_set_routine    proc    far
  320.     push    ds
  321.     push    di
  322.     push    si
  323.     mov    si,cs
  324.     mov    ds,si
  325.     cmp    ax,9
  326.     jbe    DoIt
  327.     jmp    Exit
  328. DoIt:    add    ax,ax
  329.     mov    si,ax
  330.     jmp    WORD PTR mode_set_table[si]
  331. mode_set_table  label    word
  332.     dw    offset mode_0
  333.     dw    offset mode_1
  334.     dw    offset mode_2
  335.     dw    offset mode_3
  336.     dw    offset mode_4
  337.     dw    offset mode_5
  338.     dw    offset mode_6
  339.     dw    offset mode_7
  340.     dw    offset mode_8
  341.     dw    offset mode_9
  342. mode_0: mov    si,offset text_mode_table    ; 80x25 text
  343.     mov    bx,def_nc
  344.     mov    cx,80
  345.     mov    dx,25
  346.     jmp    Lookup
  347. mode_1: mov    si,offset text_mode_table    ; default text
  348.     mov    bx,def_nc
  349.     mov    cx,def_tw
  350.     mov    dx,def_th
  351.     jmp    Lookup
  352. mode_2: mov    si,offset text_mode_table    ; CX*DX text
  353.     mov    bx,def_nc
  354.     jmp    Lookup
  355. mode_3: mov    si,offset text_mode_table    ; biggest text
  356.     mov    bx,def_nc
  357.     mov    cx,Max_TW
  358.     mov    dx,Max_TH
  359.     jmp    Lookup
  360. mode_4: mov    si,offset graphics_mode_table    ; 320x200 graphics
  361.     mov    bx,def_nc
  362.     mov    cx,320
  363.     mov    dx,200
  364.     jmp    Lookup
  365. mode_5: mov    si,offset graphics_mode_table    ; default graphics
  366.     mov    bx,def_nc
  367.     mov    cx,def_gw
  368.     mov    dx,def_gh
  369.     jmp    Lookup
  370. mode_6: mov    si,offset graphics_mode_table    ; CX*DX graphics
  371.     mov    bx,def_nc
  372.     jmp    Lookup
  373. mode_7: mov    si,offset graphics_mode_table    ; biggest non-interlaced gr
  374.     mov    bx,def_nc
  375.     mov    cx,Max_GWn
  376.     mov    dx,Max_GHn
  377.     jmp    Lookup
  378. mode_8: mov    si,offset graphics_mode_table    ; biggest graphics
  379.     mov    bx,def_nc
  380.     mov    cx,Max_GW
  381.     mov    dx,Max_GH
  382.     jmp    Lookup
  383. mode_9: mov    si,offset graphics_mode_table    ; CX*DX graphics w/ BX colors
  384. ;
  385. ; At this point:
  386. ;   SI points to the table to search (text or graphics)
  387. ;   BX has colors
  388. ;   CX has width
  389. ;   DX has height
  390. ;
  391. Lookup: xor    ax,ax                ; last color number seen
  392. Find_C: cmp    [si+4],ax            ; last color number == this?
  393.     je    Same_C
  394.     jb    Prev_C                ; end of table -- use last color
  395.     cmp    BYTE PTR [si+6],0ffh        ; valid entry ?
  396.     je    Prev_C                ; not -- use last color
  397.     mov    ax,[si+4]            ; record color number
  398.     mov    di,si                ; start of entries w/ this color
  399.     cmp    ax,bx                ; enough colors ?
  400.     jae    Find_S
  401. Same_C: add    si,8
  402.     jmp    Find_C
  403. Prev_C: or    ax,ax                ; found any color at all?
  404.     je    Exit
  405. ;
  406. ; At this point:
  407. ;   DI points into the table to the first entry with the desired color
  408. ;      number (either it has enough colors or it is the highest color
  409. ;      number supported by the driver). Additionally, at least the
  410. ;      first (= smallest size) entry for this color is valid (has a
  411. ;      valid BIOS number).
  412. ;   AX has the color number adjusted for the driver
  413. ;   CX has width
  414. ;   DX has height
  415. ;
  416. Find_S: cmp    [di+4],ax            ; still the same color #?
  417.     jne    Prev_S
  418.     cmp    BYTE PTR [di+6],0ffh        ; valid entry ?
  419.     je    Prev_S
  420.     cmp    [di],cx
  421.     jb    Next_S
  422.     cmp    [di+2],dx
  423.     jae    GotIt
  424. Next_S: add    di,8
  425.     jmp    Find_S
  426. Prev_S: sub    di,8
  427. ;
  428. ; At this point:
  429. ;   DI points to the table entry we want to set up
  430. ;
  431. GotIt:  mov    ax,[di+6]            ; BIOS mode number
  432.     or    ah,ah                ; special ?
  433.     je    doBIOS
  434.     mov    al,ah
  435.     xor    ah,ah
  436.     dec    ax
  437.     add    ax,ax
  438.     mov    si,ax
  439.     call    WORD PTR special_setup_table[si]
  440.     jmp    RetVal
  441. doBIOS: int    10h
  442.     mov    bx,GRD_1_PLANE
  443.     cmp    WORD PTR [di+4],2        ; 2 colors ?
  444.     je    doFLAG
  445.     mov    bx,GRD_4_PLANES
  446.     cmp    WORD PTR [di+4],16        ; 16 colors ?
  447.     je    doFLAG
  448.     mov    bx,GRD_8_PLANES
  449.     cmp    WORD PTR [di+4],256        ; 256 colors ?
  450.     je    doFLAG
  451.     mov    bx,GRD_16_PLANES
  452.     cmp    WORD PTR [di+4],32768        ; 32K colors ?
  453.     je    doFLAG
  454.     mov    bx,GRD_PLANE_MASK        ; something is wrong!!
  455. doFLAG: or    bx,mode_W
  456. RetVal: mov    cx,[di]
  457.     mov    dx,[di+2]
  458. Exit:    pop    si
  459.     pop    di
  460.     pop    ds
  461.     ret
  462. mode_set_routine    endp
  463.  
  464.  
  465. ;--------------------------------------------------------------------------
  466. ; PAGING ROUTINE
  467. ;
  468. ;  Entry: AH=read page
  469. ;      AL=write page
  470. ;
  471. ;  Exit: VGA configured.
  472. ;     AX,BX,CX,DX,SI,DI may be trashed
  473. ;
  474. ;  NOTE: This runs in protected mode!  Don't mess with the segment registers!
  475. ;     This code must be relocatable and may not reference any data!
  476. ;--------------------------------------------------------------------------
  477.     assume  ds:nothing, es:nothing
  478.  
  479. paging_routine  proc    far
  480. ;     and     al,0fh
  481. ;     mov     cl,4
  482. ;     shl     ah,cl
  483. ;     and     ah,0f0h
  484. ;     or     al,ah
  485.     and    al,1fh
  486.     or    al,20h
  487.     mov    dx,03cdh
  488.     out    dx,al
  489.     ret
  490. paging_routine  endp
  491.  
  492. _TEXT    ends
  493.     end
  494.  
  495.